# -*- mode: python ; coding: utf-8 -*-
"""
PyInstaller spec file for AI-Powered SSH Terminal
Builds a standalone executable with all dependencies
"""

import os
import sys
from pathlib import Path

# Get the current directory
current_dir = Path.cwd()

# Define application metadata
app_name = 'AI-Terminal'
app_version = '2.0.0'
app_description = 'AI-Powered SSH Terminal with Local LLaMA Model'

# Data files to include
datas = [
    # HTML frontend
    ('ai-terminal.html', '.'),
    
    # Database schema and templates (if any)
    ('*.sql', '.') if Path('*.sql').exists() else None,
    
    # Configuration files
    ('environment.yml', '.'),
    ('requirements.txt', '.'),
    
    # Documentation
    ('README.md', '.'),
]

# Remove None entries
datas = [item for item in datas if item is not None]

# Hidden imports - modules that PyInstaller might miss
hiddenimports = [
    # FastAPI and dependencies
    'fastapi',
    'fastapi.staticfiles',
    'fastapi.responses',
    'fastapi.middleware.cors',
    'uvicorn',
    'uvicorn.logging',
    'uvicorn.loops',
    'uvicorn.loops.auto',
    'uvicorn.protocols',
    'uvicorn.protocols.websockets',
    'uvicorn.protocols.websockets.auto',
    'uvicorn.protocols.http',
    'uvicorn.protocols.http.auto',
    
    # SSH and crypto
    'paramiko',
    'paramiko.transport',
    'paramiko.client',
    'paramiko.channel',
    'cryptography',
    'cryptography.fernet',
    'bcrypt',
    
    # Database
    'sqlite3',
    
    # AI/ML dependencies
    'llama_cpp',
    'llama_cpp.llama',
    'llama_cpp.llama_cpp',
    
    # Async and networking
    'websockets',
    'websockets.server',
    'websockets.client',
    'aiofiles',
    'asyncio',
    
    # Data handling
    'pydantic',
    'pydantic.fields',
    'pydantic.validators',
    'orjson',
    'json',
    
    # System monitoring
    'psutil',
    
    # Logging
    'structlog',
    'logging',
    'logging.handlers',
    
    # Standard library modules that might be missed
    'threading',
    'multiprocessing',
    'queue',
    'datetime',
    'pathlib',
    'subprocess',
    'socket',
    'ssl',
]

# Binaries to include (mostly for LLaMA model support)
binaries = []

# Add LLaMA model binaries if available
try:
    import llama_cpp
    llama_cpp_path = Path(llama_cpp.__file__).parent
    # Include any .dll/.so files from llama-cpp-python
    for ext in ['*.dll', '*.so', '*.dylib']:
        binaries.extend([(str(f), '.') for f in llama_cpp_path.glob(ext)])
except ImportError:
    pass

# Exclude modules to reduce size
excludes = [
    # Development tools
    'pytest',
    'black',
    'isort',
    'mypy',
    
    # Jupyter/IPython
    'IPython',
    'jupyter',
    'notebook',
    
    # GUI frameworks not needed
    'tkinter',
    'PyQt5',
    'PyQt6',
    'PySide2',
    'PySide6',
    
    # Documentation tools
    'sphinx',
    'docutils',
    
    # Testing frameworks
    'unittest',
    'nose',
    
    # Large ML libraries not used
    'torch',
    'tensorflow',
    'numpy.distutils',
    'scipy.spatial.cKDTree',
]

# Main application analysis
a = Analysis(
    ['app.py'],
    pathex=[str(current_dir)],
    binaries=binaries,
    datas=datas,
    hiddenimports=hiddenimports,
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=excludes,
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=None,
    noarchive=False,
)

# Remove duplicate files
pyz = PYZ(a.pure, a.zipped_data, cipher=None)

# Create executable
exe = EXE(
    pyz,
    a.scripts,
    [],
    exclude_binaries=True,
    name=app_name,
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    console=True,  # Set to False for windowed app
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    icon=None,  # Add .ico file path if you have an icon
)

# Create distribution directory
coll = COLLECT(
    exe,
    a.binaries,
    a.zipfiles,
    a.datas,
    strip=False,
    upx=True,
    upx_exclude=[],
    name=app_name,
)

# Optional: Create a one-file executable (larger file, slower startup)
# Uncomment the following to create a single executable file
"""
exe_onefile = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name=f'{app_name}-portable',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    icon=None,
)
"""